'use strict';
const Service = require('egg').Service;

class ArticleService extends Service {
  constructor(ctx) {
    super(ctx);
    this.user = {};
  }

  async create(params) {
    const { mysql } = this.app;
    const { config } = this.app;
    try {
      const {
        categoryId,
        title,
        cover,
        abstract,
        content,
        keywords,
        tags,
        source,
        status,
      } = params;
      const created_at = new Date();
      const updated_at = new Date();
      const url = config.BASE_ARTICLE_URL;
      const result = await mysql.query(`INSERT INTO cms_article(category_id, title, cover, abstract, content , keywords, tags, source, url, status, created_at, updated_at)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
      [ categoryId, title, cover, abstract, content, keywords, tags, source, url, status, created_at, updated_at ]);

      if (result.affectedRows === 1) {
        await mysql.query('UPDATE `cms_article` SET `url`=? WHERE `id`=?', [ `${url}/${result.insertId}`, result.insertId ]);
        return result.insertId;
      }
      this.ctx.throw(result.message);
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }

  async find(params) {
    const { Sequelize: { Op }, model } = this.app;
    const { Cms: { Article } } = model;
    const { helper: { pagination } } = this.ctx;
    try {
      const { categoryId, title, status, page, size } = params;
      console.log('categoryId: ', categoryId, page, size);
      const pagger = pagination(page, size);
      const count = await Article.count();
      const articles = await Article.findAll({
        where: {
          category_id: {
            ...(categoryId ? { [Op.eq]: categoryId } : { [Op.ne]: null }),
          },
          title: {
            ...(title ? { [Op.like]: `%${title}%` } : { [Op.ne]: null }),
          },
          status: {
            ...(status ? { [Op.eq]: status } : { [Op.ne]: null }),
          },
        },
        limit: pagger.limit,
        offset: pagger.offset,
      });

      return {
        pagination: {
          total: count,
          page: pagger.page,
          size: pagger.size,
        },
        list: articles,
      };
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }

  async findOne(params) {
    const { mysql } = this.app;
    try {
      const { id } = params;
      const select = 'SELECT A.`id`, A.`category_id`, A.`title`, A.`cover`, A.`abstract`, A.`content`, A.`keywords`, A.`tags`, A.`status`, A.`updated_at`, A.`source`, A.`url`, A.`created_at`, A.`published_at`, IFNULL( B.`comment_count`, 0 ) AS `comment_count`, IFNULL( C.`zan_count`, 0 ) AS `zan_count` FROM `cms_article` AS A LEFT JOIN ( SELECT `topic_id`, count( * ) AS `comment_count` FROM `cms_comment` GROUP BY `topic_id` ) AS B ON ( A.`id` = B.`topic_id` ) LEFT JOIN ( SELECT `type_id`, count( * ) AS `zan_count` FROM `cms_zan` GROUP BY `type_id` ) AS C ON ( A.`id` = C.`type_id` )';
      const wheres = 'where id = ?';
      const result = await mysql.query([ select, wheres ].join(' '), [ id ]);
      if (result.length) {
        return result[0];
      }
      this.ctx.throw(404, 'the id was not found');
    } catch (error) {
      this.ctx.throw(error.status || 500, error.message);
    }
  }

  async update(params) {
    const { mysql } = this.app;
    try {
      const {
        id,
        categoryId,
        cover,
        title,
        abstract,
        content,
        keywords,
        tags,
        source,
        status,
      } = params;
      const updated_at = new Date();
      const result = await mysql.query('UPDATE `cms_article` SET `category_id`=?, `title`=?, `cover`=?, `abstract`=?, `content` =?, `keywords`=?, `tags`=?, `source`=?, `status`=?, `updated_at`=? WHERE `id`=?',
        [ categoryId, title, cover, abstract, content, keywords, tags, source, status, updated_at, id ]);

      if (result.affectedRows === 1) {
        return {};
      }
      this.ctx.throw(result.message);
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }

  async destroy(params) {
    const { mysql } = this.app;
    try {
      const { id } = params;
      const result = await mysql.delete('cms_article', { id });
      return { data: result.affectedRows };
    } catch (error) {
      this.ctx.throw(500, error.message);
    }
  }
}

module.exports = ArticleService;
